#!/usr/bin/env python3
"""
Erlang MCP Server

面向 Erlang 编程语言的 MCP Server，提供 Erlang 命令行操作的工具封装。

MCP tools 列表：
- erlang_version: 获取 Erlang 版本信息
- erlang_list_operations: 执行列表操作和模式匹配
- erlang_io_formatting: 执行 IO 格式化输出到文件
- erlang_arithmetic: 执行算术运算
- erlang_process_spawning: 测试进程生成功能
- erlang_system_info: 获取系统信息和 BIF 函数调用
- erlang_tuple_operations: 执行元组操作和模式匹配
"""

import subprocess
import tempfile
import os
from typing import Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("Erlang MCP Server")

@mcp.tool()
def erlang_version() -> dict:
    """
    获取 Erlang 版本信息
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    cmd = ["erl", "-version"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_list_operations() -> dict:
    """
    执行列表操作和模式匹配
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    erl_code = "List = [1,2,3,4,5], [Head|Tail] = List, io:format(\"Head:~p,Tail:~p\", [Head, Tail]), erlang:halt()."
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_io_formatting(output_file: Optional[str] = None) -> dict:
    """
    执行 IO 格式化输出
    
    参数:
        output_file: 输出文件路径，如果为 None 则输出到标准输出
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    erl_code = "io:format(\"Hello from Erlang~n\"), erlang:halt()."
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    
    try:
        if output_file:
            with open(output_file, 'w') as f:
                result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True, timeout=30)
            # 读取文件内容作为输出
            with open(output_file, 'r') as f:
                file_content = f.read()
            return {
                "success": result.returncode == 0,
                "command": " ".join(cmd) + f" > {output_file}",
                "exit_code": result.returncode,
                "stdout": file_content,
                "stderr": result.stderr
            }
        else:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            return {
                "success": result.returncode == 0,
                "command": " ".join(cmd),
                "exit_code": result.returncode,
                "stdout": result.stdout,
                "stderr": result.stderr
            }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_arithmetic() -> dict:
    """
    执行算术运算
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    erl_code = "Result = 2 + 3 * 4, io:format(\"~p\", [Result]), erlang:halt()."
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_process_spawning() -> dict:
    """
    测试进程生成功能
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    erl_code = "Pid = spawn(fun() -> timer:sleep(100), io:format(\"done\") end), erlang:halt()."
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_system_info(info_type: str = "node") -> dict:
    """
    获取系统信息和 BIF 函数调用
    
    参数:
        info_type: 信息类型，可选 "node"（节点信息）或 "otp"（OTP版本信息）
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    if info_type == "node":
        erl_code = "io:format(\"~s\", [node()]), erlang:halt()."
    elif info_type == "otp":
        erl_code = "io:format(\"~s\", [erlang:system_info(otp_release)]), erlang:halt()."
    else:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Unsupported info_type: {info_type}. Supported types: 'node', 'otp'"
        }
    
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def erlang_tuple_operations() -> dict:
    """
    执行元组操作和模式匹配
    
    返回:
        dict: 包含执行结果的 JSON 结构
            {
                "success": bool,
                "command": str,
                "exit_code": int,
                "stdout": str,
                "stderr": str
            }
    """
    erl_code = "Tuple = {ok, \"test\", 123}, {Status, Message, Number} = Tuple, io:format(\"Status:~p-Message:~s-Number:~p\", [Status, Message, Number]), erlang:halt()."
    cmd = ["erl", "-eval", erl_code, "-noshell"]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()